#include "init.h"

QScopedPointer<init> init::self;
QScopedPointer<initChildThread> initChildThread::self;

init* init::getInstance()
{
    if (self.isNull()) {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if (self.isNull()) {
            self.reset(new init);
        }
    }
    return self.data();
}

init::init(QObject *parent) : QThread(parent)
{
    return;
}

init::~init()
{
    return;
}

void init::run()
{
    // this->initButton();
    // this->initEdit();
    // this->initParas();
    this->initCamera();
    return;
}

void init::setParent(QObject *parent)
{
    this->parent = parent;
    return;
}

void init::setUI(Ui_visual2* ui)
{
    this->ui = ui;
    return;
}

/*void init::initButton(){
    ui->pushButton_model->setText("当前机型未选择");
    connect(ui->pushButton_connectPLC, SIGNAL(clicked()), parent, SLOT(connectPLC()));
    connect(ui->pushButton_connectCamera, SIGNAL(clicked()), parent, SLOT(connectCamera()));
    connect(ui->pushButton_model, SIGNAL(clicked()), parent, SLOT(selectModel()));
    connect(ui->pushButton_exit, SIGNAL(clicked()), parent, SLOT(exit()));
    connect(ui->pushButton_startCal, SIGNAL(clicked()), parent, SLOT(startCalModel()));
    connect(ui->pushButton_reCal, SIGNAL(clicked()), parent, SLOT(reCalModel()));
    connect(ui->pushButton_rotate, SIGNAL(clicked()), parent, SLOT(rotate()));
    connect(ui->pushButton_calFinish, SIGNAL(clicked()), parent, SLOT(calFinishModel()));
    connect(ui->pushButton_startCalCamera, SIGNAL(clicked()), parent, SLOT(startCalCamera()));
    connect(ui->pushButton_reCalCamera, SIGNAL(clicked()), parent, SLOT(reCalCamera()));
    connect(ui->pushButton_calFinishCamera, SIGNAL(clicked()), parent, SLOT(calFinishCamera()));
    connect(ui->pushButton_x, SIGNAL(clicked()), parent, SLOT(PLCTeachingX()));
    connect(ui->pushButton_y, SIGNAL(clicked()), parent, SLOT(PLCTeachingY()));
    connect(ui->pushButton_z, SIGNAL(clicked()), parent, SLOT(PLCTeachingZ()));
    connect(ui->pushButton_r, SIGNAL(clicked()), parent, SLOT(PLCTeachingR()));
    return;
}

void init::initEdit()
{
    //令PLC地址输入框只能输入IP地址+端口格式
    ui->lineEdit_PLCAddress->setValidator(new QRegExpValidator(QRegExp("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\:([0-9]|[1-9]\\d|[1-9]\\d{2}|[1-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])\\b")));
    ui->lineEdit_PLCAddress->setInputMask("000.000.000.000:00000; ");
    //ui->lineEdit_PLCAddress->setToolTip("请输入IP地址+端口号，如192.168.0.100:50000");

    //令相机曝光时间输入框只能输入数字
    ui->lineEdit_exposure->setValidator(new QIntValidator(0, 1000000, parent));

    //令相机白平衡输入框只能输入类似于1.86|1.0|2.2的格式，并给出输入掩码和提示
    ui->lineEdit_wb->setValidator(new QRegExpValidator(QRegExp("\\b(\\d+\\.\\d+\\|){2}\\d+\\.\\d+\\b")));
    ui->lineEdit_wb->setInputMask("0.00|0.00|0.00; ");
    //ui->lineEdit_wb->setToolTip("请输入白平衡参数，如1.86|1.0|2.2");

    //令图像处理参数输入框只能输入类似于255|80|25|51|1.3|0.8|1300000|500000的格式，并给出输入掩码和提示
    ui->lineEdit_process->setValidator(new QRegExpValidator(QRegExp("\\b(\\d+\\|){7}\\d+\\b")));
    ui->lineEdit_process->setInputMask("000|000|000|000|0.0|0.0|0000000|000000; ");
    //ui->lineEdit_process->setToolTip("请输入图像处理参数，如255|80|25|51|1.3|0.8|1300000|500000");

    //令相机矫正矩阵输入框只能输入类似于1.0,0.0,0.0;0.0,1.0,0.0;0.0,0.0,1.0的格式，并给出输入掩码和提示
    ui->lineEdit_perspective->setValidator(new QRegExpValidator(QRegExp("\\b(\\d+\\.\\d+\\,){2}\\d+\\.\\d+\\;){2}(\\d+\\.\\d+\\,){2}\\d+\\.\\d+\\b")));
    ui->lineEdit_perspective->setInputMask("0.0,0.0,0.0|0.0,0.0,0.0|0.0,0.0,0.0; ");
    //ui->lineEdit_perspective->setToolTip("请输入矫正矩阵，如1.0,0.0,0.0|0.0,1.0,0.0|0.0,0.0,1.0");

    //令左上角坐标输入框只能输入类似于1350,1350的格式，并给出输入掩码和提示
    ui->lineEdit_chessboardloc->setValidator(new QRegExpValidator(QRegExp("\\b\\d+\\,\\d+\\b")));
    ui->lineEdit_chessboardloc->setInputMask("0000,0000; ");
    //ui->lineEdit_chessboardloc->setToolTip("请输入左上角坐标，如1350,1350");

    //令棋盘格角点数只能输入类似于9,6的格式，并给出输入掩码和提示
    ui->lineEdit_chessboardsize->setValidator(new QRegExpValidator(QRegExp("\\b\\d+\\,\\d+\\b")));
    ui->lineEdit_chessboardsize->setInputMask("0000,0000; ");
    //ui->lineEdit_chessboardsize->setToolTip("请输入棋盘格角点数，如9,6");
    return;
}

void init::initParas(){
    //获取当前时间
    Paras::time_start=time(NULL);
    ui->label_currentTime->setText(QString::fromStdString(ctime(&Paras::time_start)));
    ui->label_runningTime->setText("0");
    ui->label_productCount->setText("0");
    ui->label_capacity->setText("0");
    ui->label_status->setText("未运行");
    ui->listWidget_testing->clear();
    ui->listWidget_testing->addItem("软件已启动，当前时间：" + QString::fromStdString(ctime(&Paras::time_start)));
    ui->listWidget_testing->addItem("请连接相机与PLC，并选择机型");
    ui->tabWidget->setCurrentIndex(0);
    return;
}*/

void init::initCamera(){
    //使用opencv获取当前可用摄像头列表
    cv::VideoCapture capture;
    cv::Mat frame;
    std::vector<cv::Point>cameraResolution;
    int cameraNum = 0;
    
    while (true)
    {
        capture.open(cameraNum);
        if (!capture.isOpened())
        {
            break;
        }
        else
        {
            //获取当前相机的分辨率
            capture >> frame;
            cameraResolution.push_back(cv::Point(frame.cols, frame.rows));
            cameraNum++;
            capture.release();
        }
    }
    //将可用摄像头列表添加到下拉菜单中
    ui->comboBox_connectCamera->clear();
    for (int i = 0; i < cameraNum; i++)
    {
        //获取第i个相机的名称
        ui->comboBox_connectCamera->addItem(QString::number(i)+"号相机"+"("+QString::number(cameraResolution[i].x)+"x"+QString::number(cameraResolution[i].y)+")");
    }
    return;
}

initChildThread::initChildThread(QObject *parent) : QObject(parent)
{
    this->parent = parent;
    return;
}

initChildThread::~initChildThread()
{
    return;
}

initChildThread* initChildThread::getInstance()
{
    if (self.isNull()) {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if (self.isNull()) {
            self.reset(new initChildThread);
        }
    }
    return self.data();
}

void initChildThread::setParent(QObject *parent)
{
    this->parent = parent;
    return;
}

void initChildThread::setUI(Ui_visual2* ui)
{
    this->ui = ui;
    return;
}

void initChildThread::initComponent()
{
    initLink();
    initImageDeal();
    initDisplay();
    initCalibration();
    return;
}

void initChildThread::initLink()
{
    return;
}

void initChildThread::initImageDeal()
{
    camera1::getInstance()->stopThread();
    camera1::getInstance()->setLocalIntervals(Paras::timerCaptureInterval);
    camera1::getInstance()->setDetectFlag(false);
    camera1::getInstance()->setSendInfoFlag(false);
    camera1::getInstance()->start();
    connect(parent,SIGNAL(sendImageDeal()),camera1::getInstance(),SLOT(process()));
    connect(camera1::getInstance(), SIGNAL(sendImage()), display::getInstance(), SLOT(setImage()));
    return;
}

void initChildThread::initDisplay()
{
    display::getInstance()->stopThread();
    display::getInstance()->setUI(ui);
    display::getInstance()->setShowImageFlag(false);
    display::getInstance()->setImage();
    display::getInstance()->start();
    return;
}

void initChildThread::initCalibration()
{
    return;
}

void initChildThread::exitComponent()
{
    camera1::getInstance()->stopThread();
    display::getInstance()->stopThread();
    return;
}

// Compare this snippet from src\common\init.cpp: